﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Media3D;
using System.Windows.Media;
using System.Windows;
using Wpf_Examples.Models;

namespace Wpf_Examples.Tools
{
    internal class CreateParticleCubeWaveHelper
    {
        /// <summary>
        /// 存储所有粒子的列表。
        /// </summary>
        private readonly List<ParticleCubeWaveModel> particleCubeWavesList;

        /// <summary>
        /// 用于绘制粒子的3D几何模型。
        /// </summary>
        private readonly GeometryModel3D geometryModel3D;

        /// <summary>
        /// 粒子的高度，默认值为20。
        /// </summary>
        private readonly int CUBOIDHEIGHT = 20;

        /// <summary>
        /// 鼠标的半径影响范围，默认值为1000。
        /// </summary>
        private readonly int MOUSERADIUS = 1000;

        /// <summary>
        /// X方向上的粒子数量。
        /// </summary>
        private int XParticleCount;

        /// <summary>
        /// Y方向上的粒子数量。
        /// </summary>
        private int YParticleCount;

        /// <summary>
        /// 获取粒子模型。
        /// </summary>
        public Model3D ParticleModel => geometryModel3D;

        /// <summary>
        /// 构造函数，初始化粒子系统。
        /// </summary>
        /// <param name="amountX">X方向上的粒子数量。</param>
        /// <param name="amountY">Y方向上的粒子数量。</param>
        /// <param name="color">粒子的颜色。</param>
        public CreateParticleCubeWaveHelper(int amountX, int amountY, Color color)
        {
            XParticleCount = amountX;
            YParticleCount = amountY;

            particleCubeWavesList = new List<ParticleCubeWaveModel>();
            geometryModel3D = new GeometryModel3D { Geometry = new MeshGeometry3D() };
            var material = new DiffuseMaterial(new SolidColorBrush(color));
            geometryModel3D.Material = material;
        }
        /// <summary>
        /// 初始化粒子的位置和大小。
        /// </summary>
        /// <param name="size">粒子的大小。</param>
        public void SpawnParticle(double size)
        {
            // 初始化粒子位置和大小
            for (int ix = 0; ix < XParticleCount; ix++)
            {
                for (int iy = 0; iy < YParticleCount; iy++)
                {
                    var p = new ParticleCubeWaveModel
                    {
                        Position = new Point3D(ix * size, iy * size, 0),
                        Width = size,
                        Height = CUBOIDHEIGHT,
                    };
                    particleCubeWavesList.Add(p);
                }
            }
        }
        /// <summary>
        /// 根据鼠标位置更新粒子的高度。
        /// </summary>
        /// <param name="mp">鼠标位置。</param>
        public void Update(Point mp)
        {
            foreach (var p in particleCubeWavesList)
            {
                // 计算鼠标位置到粒子中心的距离
                double c = Math.Pow(Math.Pow(mp.X - p.Position.X, 2) + Math.Pow(mp.Y - p.Position.Y, 2), 0.5);
                p.Height = (MOUSERADIUS / (c + CUBOIDHEIGHT)) * CUBOIDHEIGHT;
            }
            UpdateGeometry();
        }
        /// <summary>
        /// 更新几何体的数据。
        /// </summary>
        private void UpdateGeometry()
        {
            var positions = new Point3DCollection();
            var indices = new Int32Collection();
            // 清空旧的数据，防止数据叠加
            positions.Clear();
            indices.Clear();
            // 遍历所有粒子，更新几何体数据
            for (var i = 0; i < particleCubeWavesList.Count; ++i)
            {
                var positionIndex = i * 8;
                var p = particleCubeWavesList[i];
                // 计算粒子的八个顶点位置
                var p1 = new Point3D(p.Position.X, p.Position.Y, p.Position.Z);
                var p2 = new Point3D(p.Position.X + p.Width, p.Position.Y, p.Position.Z);
                var p3 = new Point3D(p.Position.X + p.Width, p.Position.Y + p.Width, p.Position.Z);
                var p4 = new Point3D(p.Position.X, p.Position.Y + p.Width, p.Position.Z);
                var p5 = new Point3D(p.Position.X, p.Position.Y, p.Position.Z + p.Height);
                var p6 = new Point3D(p.Position.X + p.Width, p.Position.Y, p.Position.Z + p.Height);
                var p7 = new Point3D(p.Position.X + p.Width, p.Position.Y + p.Width, p.Position.Z + p.Height);
                var p8 = new Point3D(p.Position.X, p.Position.Y + p.Width, p.Position.Z + p.Height);
                // 添加顶点位置
                positions.Add(p1);
                positions.Add(p2);
                positions.Add(p3);
                positions.Add(p4);
                positions.Add(p5);
                positions.Add(p6);
                positions.Add(p7);
                positions.Add(p8);
                // 添加三角形索引，定义粒子的表面
                indices.Add(positionIndex);
                indices.Add(positionIndex + 1);
                indices.Add(positionIndex + 3);
                indices.Add(positionIndex + 1);
                indices.Add(positionIndex + 2);
                indices.Add(positionIndex + 3);
                indices.Add(positionIndex);
                indices.Add(positionIndex + 4);
                indices.Add(positionIndex + 3);
                indices.Add(positionIndex + 4);
                indices.Add(positionIndex + 7);
                indices.Add(positionIndex + 3);
                indices.Add(positionIndex + 4);
                indices.Add(positionIndex + 6);
                indices.Add(positionIndex + 7);
                indices.Add(positionIndex + 4);
                indices.Add(positionIndex + 5);
                indices.Add(positionIndex + 6);
                indices.Add(positionIndex);
                indices.Add(positionIndex + 4);
                indices.Add(positionIndex + 1);
                indices.Add(positionIndex + 1);
                indices.Add(positionIndex + 4);
                indices.Add(positionIndex + 5);
                indices.Add(positionIndex + 1);
                indices.Add(positionIndex + 2);
                indices.Add(positionIndex + 6);
                indices.Add(positionIndex + 6);
                indices.Add(positionIndex + 5);
                indices.Add(positionIndex + 1);
                indices.Add(positionIndex + 2);
                indices.Add(positionIndex + 3);
                indices.Add(positionIndex + 7);
                indices.Add(positionIndex + 7);
                indices.Add(positionIndex + 6);
                indices.Add(positionIndex + 2);
            }
            // 更新几何体的数据
              ((MeshGeometry3D)geometryModel3D.Geometry).Positions = positions;
            ((MeshGeometry3D)geometryModel3D.Geometry).TriangleIndices = indices;
        }
    }
}
